package com.atguigu.ssyx.user.controller;

import com.alibaba.fastjson.JSONObject;
import com.atguigu.ssyx.common.constant.RedisConst;
import com.atguigu.ssyx.common.exception.SsyxException;
import com.atguigu.ssyx.common.result.Result;
import com.atguigu.ssyx.common.result.ResultCodeEnum;
import com.atguigu.ssyx.common.security.AuthContextHolder;
import com.atguigu.ssyx.common.utils.JwtHelper;
import com.atguigu.ssyx.enums.UserType;
import com.atguigu.ssyx.enums.user.User;
import com.atguigu.ssyx.user.service.IUserService;
import com.atguigu.ssyx.user.utils.HttpClientUtils;
import com.atguigu.ssyx.user.utils.WxOpenProperties;
import com.atguigu.ssyx.vo.user.LeaderAddressVo;
import com.atguigu.ssyx.vo.user.UserLoginVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.concurrent.TimeUnit;


@RequiredArgsConstructor
@RestController
@RequestMapping("/api/user/weixin")
@Slf4j
@Api(tags = "微信用户信息接口")
public class WerxinApiController {

    private final IUserService userService;
    private final WxOpenProperties wxOpenProperties;
    private final RedisTemplate redisTemplate;

    //    const get_wx_login = '/user/weixin/wxLogin' // 微信用户登陆
    @ApiOperation("微信用户登录接口")
    @GetMapping("/wxLogin/{code}")
    public Result wxLogin(@PathVariable String code) {
        //1.通过调用微信的接口（wx.login）获取code

        log.info("微信用户登录接口，code={}", code);
        if (code.isEmpty()) {
            throw new SsyxException(ResultCodeEnum.FETCH_USERINFO_ERROR);
        }
        //2.拿着code+appid+secret去请求微信接口服务

        String appId = wxOpenProperties.getAppId();
        String appSecret = wxOpenProperties.getAppSecret();

        StringBuffer sb = new StringBuffer();
/*
        appid	string	是	小程序 appId
        secret	string	是	小程序 appSecret
        js_code	string	是	登录时获取的 code，可通过wx.login获取
        grant_type	string	是	授权类型，此处只需填写 authorization_code*/
        String url = sb.append("https://api.weixin.qq.com/sns/jscode2session?")
                .append("appid=").append(appId)
                .append("&secret=").append(appSecret)
                .append("&js_code=").append(code)
                .append("&grant_type=authorization_code").toString();
        //3.使用httpclient 工具请求得到session_key+openid


        String result = null;
        try {
            result = HttpClientUtils.get(url);
        } catch (Exception e) {
            throw new SsyxException(ResultCodeEnum.FETCH_ACCESSTOKEN_FAILD);
        }
        log.info("使用code获取的access_token结果是：，result={}", result);
        JSONObject resultJson = JSONObject.parseObject(result);//将json字符串转为JSONObject对象
        String openId = resultJson.getString("openid");
        String sessionKey = resultJson.getString("session_key");


        //4.操作user表，判断是否是第一次登录，使用openId查询，如果有就说明不是第一次登录
        //先根据openId查询数据库，如果没有查到就说明是新用户
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getOpenId, openId);
        //openId是微信用户的唯一标识
        User user = userService.getOne(wrapper);
        if (user == null) {
            //，如果没有查到就说明是新用户
            user = new User();
            user.setOpenId(openId);
            user.setNickName(openId);
            user.setPhotoUrl("");
            user.setUserType(UserType.USER);//默认是会员用户
            user.setIsNew(0);//是新用户
            userService.save(user);
        }

        //5.根据userid查询提货点和团长信息
        //user表里的id是与 user_delivery 表里的 user_id 联合查询 leader_id
        //然后根据leader_id到 leader 表里查询 leader_name

        LeaderAddressVo leaderAddressVo = userService.getLeaderAddressByUserId(user.getId());

        //6,使用jwt工具根据userid和username生成token

        String token = JwtHelper.createToken(user.getId(), user.getNickName());
        //7. 获取当前登录的用户信息，存入redis当中

        UserLoginVo userLoginVo = userService.getUserLoginVo(user.getId());


        redisTemplate.opsForValue().set(RedisConst.USER_LOGIN_KEY_PREFIX
                + user.getId(), userLoginVo, RedisConst.USERKEY_TIMEOUT, TimeUnit.DAYS);

        //8.需要数据封装到map
        HashMap<String, Object> map = new HashMap<>();
        map.put("token", token);
        map.put("user", user);
        map.put("leaderAddressVo", leaderAddressVo);
        return Result.ok(map);

    }

    @PostMapping("/auth/updateUser")
    @ApiOperation(value = "更新用户昵称与头像")
    public Result updateUser(@RequestBody User user) {
        User user1 = userService.getById(AuthContextHolder.getUserId());
        //把昵称更新为微信用户
        user1.setNickName(user.getNickName().replaceAll("[ue000-uefff]", "*"));
        user1.setPhotoUrl(user.getPhotoUrl());
        userService.updateById(user1);
        return Result.ok(null);
    }
}
